package xj.graph2d.encoder;

import java.awt.Color;
import java.awt.geom.Rectangle2D;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.svggen.SVGGraphics2D;
import org.apache.batik.transcoder.Transcoder;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.JPEGTranscoder;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.batik.transcoder.image.TIFFTranscoder;
import org.w3c.dom.DOMImplementation;

import xj.graph2d.AbstractEncoder;
import xj.graph2d.DrawCanvas;
import xj.graph2d.View;

public class BatikImageEncoder extends AbstractEncoder {

  public BatikImageEncoder() {
    transparent = false;
  }

  public BatikImageEncoder(String name, String fileExtension,
      String fileDescription, int imageType, View view) {
    super(name, fileExtension, fileDescription, view);
    this.imageType = imageType;
    transparent = false;
  }

  public void setImageType(int imageType) {
    this.imageType = imageType;
  }

  @Override
  public void setImageType(String type) {
    if ("jpg".equals(type) || "jpeg".equals(type)) {
      imageType = JPEG;
    } else if ("png".equals(type)) {
      imageType = PNG;
    } else if ("tiff".equals(type) || "tif".equals(type)) {
      imageType = TIFF;
    }
  }

  @Override
  public void encode(String filename, Rectangle2D r) throws IOException {
    if (view != null) {
      DrawCanvas canvas = view.getCanvas();
      if (filename != null && canvas != null && r != null) {
	int mw = (int) view.getMarginWidth();
	int mh = (int) view.getMarginHeight();
	int w = (int) r.getWidth() + 2 * mw;
	int h = (int) r.getHeight() + 2 * mw;
	// DOMImplementation domImpl =
	// GenericDOMImplementation.getDOMImplementation();

	DOMImplementation domImpl = SVGDOMImplementation.getDOMImplementation();
	String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;

	// System.out.println("svgNS=" + svgNS);

	org.w3c.dom.Document document = domImpl.createDocument(svgNS, "svg",
	    null);
	// org.w3c.dom.Document document = domImpl.createDocument(null,
	// "svg", null);
	org.w3c.dom.Element root = document.getDocumentElement();
	SVGGraphics2D svgGenerator = new SVGGraphics2D(document);
	setRenderingHints(svgGenerator);
	if (!transparent) {
	  Color bg = view.getBackgroundColor();
	  svgGenerator.setColor(bg);
	  svgGenerator.fillRect(0, 0, w, h);
	}

	drawWaterMark(svgGenerator, 0, 0, w, h);

	svgGenerator.translate(-r.getX() + mw, -r.getY() + mh);
	view.paintCanvas(svgGenerator, null, true); // draw all objects
	org.w3c.dom.Element svgRoot = svgGenerator.getRoot();

	/*
         * System.out.println("=== Document tree ===");
         * xj.xml.XMLParser.indentWalk(document, 1); System.out.println("===
         * Document tree end ===");
         */

	document.replaceChild(svgRoot, root);
	svgRoot.setAttributeNS(null, "width", Integer.toString(w));
	svgRoot.setAttributeNS(null, "height", Integer.toString(h));

	/*
         * System.out.println("=== SVGroot tree ===");
         * xj.xml.XMLParser.indentWalk(svgRoot, 2); System.out.println("===
         * SVGroot tree end ===");
         */

	Transcoder t;
	switch (imageType) {
	case JPEG:
	  t = new JPEGTranscoder();
	  break;

	case TIFF:
	  t = new TIFFTranscoder();
	  break;

	case PNG:
	default:
	  t = new PNGTranscoder();
	  break;
	}
	// t.addTranscodingHint(JPEGTranscoder.KEY_QUALITY,
	// new Float(.8));

	TranscoderInput input = new TranscoderInput(document);
	BufferedOutputStream bos = new BufferedOutputStream(
	    new FileOutputStream(filename));
	TranscoderOutput output = new TranscoderOutput(bos);
	try {
	  t.transcode(input, output);
	} catch (TranscoderException ex) {
	  ex.printStackTrace();
	}
	bos.flush();
	bos.close();
      }
    }
  }

  protected int imageType;

}
